// Copyright (c) Microsoft Corporation. All rights reserved.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Globalization;
using System.Xml;
using System.Xml.Serialization;

using Microsoft.TeamFoundation.Migration.Toolkit.Wit;
using Microsoft.TeamFoundation.WorkItemTracking.Client;

namespace Microsoft.TeamFoundation.Migration.Toolkit.Linking
{
    /// <summary>
    /// Related work item link.
    /// </summary>
    [Serializable]
    public class WorkItemRelatedLink: WorkItemLink
    {
        private string m_originalTarget;                    // Original link's target

        /// <summary>
        /// Parameterless constructor for serialization.
        /// </summary>
        public WorkItemRelatedLink()
        {
        }

        /// <summary>
        /// Public constructor for related links.
        /// </summary>
        /// <param name="source">Source work item</param>
        /// <param name="targetUri">Id of the target work item</param>
        /// <param name="comment">Link's comment</param>
        public WorkItemRelatedLink(
            string sourceUri,
            string targetUri,
            string comment)
            : base(sourceUri, targetUri, comment)
        {
            m_originalTarget = TargetUri;
        }

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="source">Source work item</param>
        /// <param name="l">Original related link</param>
        internal WorkItemRelatedLink(
            string sourceUri,
            RelatedLink l)
            : base(sourceUri, TfsWorkItemHandler.UriFromId(l.RelatedWorkItemId.ToString(CultureInfo.InvariantCulture)), l.Comment)
        {
            m_originalTarget = TargetUri;
        }

        /// <summary>
        /// Creates a copy of the link pointing to the given target.
        /// </summary>
        /// <param name="targetUri">URI of the new target</param>
        /// <returns>Link copy</returns>
        public override ILink Redirect(
            string targetUri)
        {
            if (string.IsNullOrEmpty(targetUri))
            {
                throw new ArgumentNullException("targetUri");
            }
            WorkItemRelatedLink copy = new WorkItemRelatedLink(SourceUri, targetUri, Comment);
            copy.m_originalTarget = TargetUri;
            return copy;
        }

        /// <summary>
        /// Submits link operation into the update package.
        /// </summary>
        /// <param name="action">Link action</param>
        /// <param name="target">TFS update statement</param>
        public override void UpdateTfs(
            AssociationAction action,
            object target)
        {
            TfsWorkItemUpdate update = target as TfsWorkItemUpdate;
            if (update == null)
            {
                throw new ToolkitArgException("update");
            }
            if (action == AssociationAction.Add)
            {
                update.AddWorkItemLink(TfsWorkItemHandler.IdFromUri(TargetUri), Comment);
            }
            else
            {
                Debug.Assert(action == AssociationAction.Remove, "Unsupported action!");
                Debug.Assert(m_originalTarget != null, "No original target!");
                update.RemoveWorkItemLink(TfsWorkItemHandler.IdFromUri(m_originalTarget));
            }
        }
    }
}
